# -*- encoding=utf8 -*-
__author__ = "chen"

import json
import os
import random
from multiprocessing import Process

from airtest.core.android import Android
from airtest.core.api import *
from paddleocr import PaddleOCR
import pandas as pd






class Game():
    def __init__(self):
        self.base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        self.config_path = os.path.join(self.base_path,"config","init_config.json")
        self.devs = self.adb_devices()
        self.Init()


    def Init(self):
        for dev in self.devs:
            connect_device(f'Android:///{dev}')


    def get_config(self):
        # 从配置文件中获取设备列表信息
        with open(self.config_path, "r", encoding="utf-8") as f:
            lines = json.load(f)
        print(f"从配置文件中获取的设备信息：{lines}")
        return lines["dev"]


    def run_command(self,command):
        read_result=[]
        result = os.popen(command).readlines()
        for i in range(len(result)):
            temp = result[i].strip().replace("\t"," ")
            if temp:
                read_result.append(temp)
        print(read_result)
        return read_result

    def adb_devices(self):
        '''
        返回连接设备数量（有效）
        :param devs: 设备seilo 编号列表
        :return: 返回有效连接设备数量
        '''
        devs = self.get_config()
        device_list = []
        for i in range(len(devs)):
            try:
                if ":" in devs[i]:
                    result = self.run_command(f"adb connect {devs[i]}")
                    if devs[i] not in result[0]:
                        continue
                connect_device(f'Android:///{devs[i]}')
                device_list.append(devs[i])
            except:
                print(f"连接异常，请确认设备是否上线：{devs[i]}")
        print(f"连接设备：{device_list}")
        return device_list


    def get_screen_size(self,dev):

        device = Android(serialno=dev)
        width, height = device.get_current_resolution()
        return width, height

    def app_touch(self,pcos,x_ofset=[0,0],y_ofset=[0,0],times=1, **kwargs):
        '''
        重构点击命令，增加偏移
        :param pcos: 点击控件中心坐标，如（10，20）
        :param x_ofset: x方向偏移区间，[min.max]，默认偏移为0
        :param y_ofset: y方向偏移区间，[min.max]，默认偏移为0
        :param times: 点击次数，默认点击1次
        :param kwargs:
        :return:
        '''
        x_ofset = random.randint(x_ofset[0], x_ofset[1])
        y_ofset = random.randint(y_ofset[0], y_ofset[1])
        print(f"点击坐标为（{(pcos[0] + x_ofset, pcos[1] + y_ofset)}）")
        touch((pcos[0] + x_ofset, pcos[1] + y_ofset),times=times,**kwargs)


    '''
     说明：
        以下是OCR文字识别的方法
    '''

    def get_value_by_OCR(self,img_path):
        '''
        将图片中的文字识别出来，并返回所有识别的对结果
        :param img_path:
        :return:
        '''
        # 如果你的机器有 GPU 并且安装了 paddlepaddle-gpu，可以添加 use_gpu=True 参数来启用 GPU 加速
        ocr = PaddleOCR(use_angle_cls=True, lang='ch', use_gpu=True)
        result = ocr.ocr(img_path, cls=True)  # cls=True 表示启用方向分类器
        return result[0]

    def get_value_by_OCR_region(self,dev,region=[0,1,0,1]):
        '''
        获取区域内的所有文字
        :param dev:安卓设备的序列号
        :param region:查找的关键词的区域比例，分别为height和withd的比例值,形式”井 "字形，1表示全图查找,先两横再两竖
        :return:
        '''
        # 1.截图
        img_file = os.path.join(self.base_path,"out","picture","test_temp_01.png")
        set_current(dev)
        snapshot(img_file)
        # 如果你的机器有 GPU 并且安装了 paddlepaddle-gpu，可以添加 use_gpu=True 参数来启用 GPU 加速
        ocr = PaddleOCR(use_angle_cls=True, lang='ch', use_gpu=True)
        result = ocr.ocr(img_file, cls=True)  # cls=True 表示启用方向分类器
        print(f"全图识别到的文字数据：{result[0]}")

        ret_data = result[0]
        width, height = self.get_screen_size(dev)

        top_heng = height * region[0]
        bottom_heng = height * region[1]
        left_shu = width * region[2]
        right_shu = width * region[3]
        print(f"选择区域范围，两横两竖，{(top_heng, bottom_heng, left_shu, right_shu)}")
        posc_fours =[]
        for i in range(len(ret_data)):
            if (ret_data[i][0][0][1] >= top_heng) and (ret_data[i][0][0][0] >= left_shu) and (
                    ret_data[i][0][2][1] <= bottom_heng) and (ret_data[i][0][2][0] <= right_shu):
                posc_fours.append(ret_data[i])
        print(f"根据比例因子：{region},识别到的文字数据：{posc_fours}")
        return posc_fours


    def app_touch_by_OCR_region(self,dev,*keywords,is_touch=False,region=[0,1,0,1],x_ofset=[0,0],y_ofset=[0,0],times=1):
        '''
        图片中,【锁定区域】查找关键字，并将执行点击操作
        :param dev:设备序列号
        :param keyword:查找的关键词的列表,一句话提前关键词，可多个
        :param is_touch:判断是否点击
        :param region:查找的关键词的区域比例，分别为height和withd的比例值,形式”井 "字形，1表示全图查找,先两横再两竖
        :param x_ofset: x方向偏移区间，[min.max]，默认偏移为0
        :param y_ofset: y方向偏移区间，[min.max]，默认偏移为0
        :param times: 点击次数，默认点击1次
        :return:
        '''
        # 1.截图
        img_file = os.path.join(self.base_path,"out","picture","test_temp_02.png")
        set_current(dev)
        snapshot(img_file)
        # 2.识别
        ret = self.get_value_by_OCR(img_file)
        print(f"获取【所有】的文字信息：{ret}")
        # 3.处理数据获取坐标
        ret_data= []
        for i in range(len(ret)):
            flage = []
            for kw in keywords:
                if kw in ret[i][1][0]:
                    flage.append(True)
                else:
                    flage.append(False)
            if all(flage) and flage:
                ret_data.append(ret[i])
        print(f"根据【关键字：{keywords}】获取的文字信息：{ret_data}")
        if is_touch and ret_data:
            # 4 计算区域，获取坐标
            width, height = self.get_screen_size(dev)
            top_heng = height * region[0]
            bottom_heng = height * region[1]
            left_shu = width * region[2]
            right_shu = width * region[3]
            print(f"选择区域范围，{(top_heng,bottom_heng,left_shu,right_shu)}")
            for i in range(len(ret_data)):
                if (ret_data[i][0][0][1] >= top_heng) and (ret_data[i][0][0][0] >= left_shu) and (ret_data[i][0][2][1] <=bottom_heng)and (ret_data[i][0][2][0] <=right_shu):
                    posc_four = ret_data[i][0]
                    break
            try:
                posc_center_x = int((posc_four[0][0] + posc_four[1][0])/2)
                posc_center_y = int((posc_four[0][1] + posc_four[3][1])/2)
                posc_center = (posc_center_x,posc_center_y)
                print(f"中心点坐标：{posc_center}")
                # 4.点击
                self.app_touch(posc_center,x_ofset,y_ofset,times)
            except:
                print(f"未识别到字段：{keywords}")
        else:
            return ret_data

    def dati_sanjie_by_excel(self,dev,answer_file):
        '''
        对三界情缘-三界情缘_答题
        :param dev:
        :param answer_file:
        :return:
        '''
        # 1.截图,区域识别
        ret_question = self.get_value_by_OCR_region(dev,region=[0.1,0.5,0.34,1]) # 根据题目位置，调节识别区域
        # 2.处理数据获取坐标
        ret_data= []
        df = pd.read_excel(answer_file)
        excel_all_data = df.values
        index = 0 # 用于查找excel中的几行
        for i in range(len(ret_question)):
            for j in range(len(excel_all_data)):
                keyword = excel_all_data[j][1]
                if "，" in keyword:
                    keywords = str(keyword).split("，")
                else:
                    keywords = [keyword]
                flage = []
                for kw in keywords:
                    if kw in ret_question[i][1][0]:
                        flage.append(True)
                    else:
                        flage.append(False)
                if all(flage) and flage:
                    ret_data.append(ret_question[i])
                    index = j
        print(f"根据【关键字：{keywords}】获取的文字信息：{ret_data}")
        #3 获取单个问题个数
        pattern = r'\((\d+)/(\d+)\)'
        ret_question_numbers = self.get_value_by_OCR_region(dev, region=[0.1,0.5,0.34,1])  # 根据题目位置，调节识别区域
        n = 1
        for i in range(len(ret_question_numbers)):
            if "(" in ret_question_numbers[i][1][0] or ")" in ret_question_numbers[i][1][0] or "（" in ret_question_numbers[i][1][0] or "）" in ret_question_numbers[i][1][0]: # 根据实际情况填写
                try:
                    print(f"问题答案个数：{ret_question_numbers[i][1][0]}")
                    # n = int(re.search(pattern, ret_question_numbers[i][1][0]).group(2))
                    n = int(ret_question_numbers[i][1][0][-2:-1])
                    break
                except:
                    print("未匹配到答题个数，采用默认值n=1")
        print(f"问题答案个数：{n}")
        #4 从表格中获取答案
        answer = excel_all_data[index][2]
        if answer:
            #5 根据表格答案分割
            if "，" in answer:
                answers = str(answer).split("，")
            else:
                answers = [answer]
            print(f"该题答案有：{answers}")
            #6 作答
            for i in range(n):
                ret = self.get_value_by_OCR_region(dev, region=[0.5, 0.7, 0.34,1])  # 识别出给定的答案，需要条件区间范围
                for k in range(len(ret)):
                    for itm in answers:
                        if itm in ret[k][1][0] :
                            print(f"该题答案是：{itm}")
                            self.app_touch_by_OCR_region(dev, itm, is_touch=True, region=[0.5, 0.7, 0.34,1], x_ofset=[-5, 5],y_ofset=[-60, -40], times=1) #需要条件识别的区域
                            sleep(2)
        else:
            print("未找到答案！！！！！")

    def dati_keju_by_excel(self,dev,answer_file):
        '''
        对科举乡试_答题
        :param dev:
        :param answer_file:
        :return:
        '''
        # 1.截图,区域识别
        ret = self.get_value_by_OCR_region(dev,region=[0,1,0,1]) # 根据题目位置，调节识别区域
        print(f"获取【所有】的文字信息：{ret}")
        # 2.处理数据获取坐标
        ret_data= []
        df = pd.read_excel(answer_file)
        excel_all_data = df.values
        index = 0 # 用于查找excel中的几行
        for i in range(len(ret)):
            for j in range(len(excel_all_data)):
                keyword = str(excel_all_data[j][1])
                if "，" in keyword:
                    keywords = str(keyword).split("，")
                else:
                    keywords = [keyword]
                flage = []
                for kw in keywords:
                    if kw in ret[i][1][0]:
                        flage.append(True)
                    else:
                        flage.append(False)
                if all(flage) and flage:
                    ret_data.append(ret[i])
                    index = j
        print(f"根据【关键字：{keywords}】获取的文字信息：{ret_data}")

        #3 从表格中获取答案
        answer = excel_all_data[index][2]
        #4 作答
        self.app_touch_by_OCR_region(dev, answer, is_touch=True, region=[0.33, 0.69, 0.33, 1], x_ofset=[-5, 5],y_ofset=[-2, 2], times=1)
        sleep(4)




if __name__ == '__main__':

    # device_list = adb_devices(devs)
    # for i in range(len(device_list)):
    #     p = Process(target=start_app_login,args=(device_list[i],))
    #     p.start()

    # app_touch((20,30))
    # base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # print(base_path)
    #
    gm = Game()
    # print(gm.adb_devices_counter())


    gm.get_value_by_OCR_region("bb6cc8c7")
    # connect_device(f'Android:///bb6cc8c7')
    # set_current("bb6cc8c7")